-- |
-- Module:        Hexena.Text.Hexdump
-- Stability:     Experimental
-- Portability:   Portable
--
-- 
module Hexena.Text.Hexdump 
               ( compactHexify
               , hexifyLines
               ) where

import qualified Data.ByteString.Lazy.Char8 as L8
import Data.Int
import Data.List (unfoldr)
import Text.Printf

hexifyLine :: L8.ByteString -> String
hexifyLine s | L8.null s = []
             | otherwise = printf "%-24s %-24s %s" (unwords (take 8 h)) (unwords (drop 8 h)) s'
  where s' = L8.unpack $ L8.take 16 s
        h = map (printf "%02x") s'

hexifyLines :: Int64 -> L8.ByteString -> [String]
hexifyLines pos s | pos >= L8.length s = []
                  | otherwise = (tpos ++ hexifyLine s') : hexifyLines (pos + 16) s
  where tpos = printf "%08X: " pos :: String
        s' = L8.drop pos s

-- hexifyList :: [a] -> [String]
-- hexifyList = map (printf "%02x")

compactHexify :: L8.ByteString -> [String]
compactHexify bs = zipWith (++) pos $ bSplit 16 bs'
    where bSplit i = unfoldr (\x -> if null x then Nothing else Just $ bsF $ splitAt i x)
          bsF (x, y) = (unwords x, y)
          bs' :: [String]
          bs' = map (printf "%02x") $ L8.unpack bs
          pos = map (printf "%06X: ") ([0,16..] :: [Int])
